<template>
  <el-card class="box-card">
    <input id="avatarFile" type="file" hidden @change="selectFile" />
    <el-dialog
      v-model="dialogVisible"
      destroy-on-close
      :title="zdialogStatus[dialogStatus]"
      width="35%"
    >
      <div v-show="dialogStatus == 0">
        <el-form
          @keyup.enter="adduser()"
          :model="addform"
          ref="ruleFormRef"
          :rules="rules"
          label-width="80px"
          label-position="left"
          scroll-to-error
          size="large"
        >
          <el-form-item label="手机号" prop="phone">
            <el-input autofocus v-model="addform.phone" />
          </el-form-item>
          <el-form-item label="密码" prop="password">
            <el-input v-model="addform.password" />
          </el-form-item>
        </el-form>
      </div>
      <div v-show="dialogStatus == 1">
        <div class="cropperBox">
          <el-form-item label="用户名">
            <el-input ref="ipt" v-model="username" />
          </el-form-item>
          <vue-cropper
            ref="cropper"
            :canMoveBox="true"
            :img="avatarBase64"
            :fixedBox="false"
            :autoCrop="true"
            autoCropWidth="200"
            autoCropHeight="200"
            outputType="png"
          ></vue-cropper>
        </div>
        <div class="optionBtn"></div>
      </div>
      <div v-show="dialogStatus == 2">
        <el-form-item label="角色选择">
          <el-select
            default-first-option
            clearable
            v-model="rolename"
            placeholder="请选择此用户角色"
          >
            <el-option
              v-for="e in rolelist"
              :label="e.rolename"
              :value="e.rolename"
              :key="e.rolename"
            />
          </el-select>
        </el-form-item>
      </div>
      <div v-show="dialogStatus == 3">
        <el-form label-position="top">
          <el-form-item label="按钮选择">
            <el-select
              style="width: 650px"
              default-first-option
              clearable
              multiple
              v-model="btnrole"
              tag-type="warning"
              placeholder="请选择此用户按钮权限"
              :collapse-tags="true"
              :max-collapse-tags="10"
            >
              <el-option v-for="e in btnroleinfo" :label="e.name" :value="e.value" :key="e.value" />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button :loading="modifyLoading" type="primary" @click="submit()"> 确定 </el-button>
        </span>
      </template>
    </el-dialog>
    <template #header>
      <div class="card-header">
        <h3>用户权限管理</h3>
        <div class="buttons">
          <el-button v-hasPermiss="'add'" type="primary" :icon="CirclePlus" @click="openModel"
            >增加用户</el-button
          >
          <el-button v-hasPermiss="'alldelete'" type="danger" @click="dels()" :icon="Delete"
            >批量删除</el-button
          >
          <el-button
            v-hasPermiss="'refresh'"
            type="primary"
            @click="refresh"
            color="green"
            :icon="RefreshRight"
            >刷新</el-button
          >
        </div>
      </div>
    </template>
    <el-scrollbar height="620px">
      <div class="table">
        <el-table
          height="600px"
          ref="fileTable"
          v-loading="tableLoading"
          element-loading-text="数据加载中..."
          :element-loading-spinner="svg"
          element-loading-svg-view-box="-10, -10, 50, 50"
          element-loading-background="rgba(122, 122, 122, 0)"
          :data="tableData"
          style="width: 100%"
          highlight-current-row
          @selection-change="handleSelectionChange"
          @row-click="rclick"
        >
          <el-table-column :selectable="selectable" align="center" type="selection" />
          <el-table-column :show-overflow-tooltip="true" align="center" prop="phone" label="手机号">
          </el-table-column>
          <el-table-column
            :show-overflow-tooltip="true"
            align="center"
            prop="username"
            label="用户名"
          >
            <template #default="scope">
              <span class="cp" @click.stop="copyText(scope.row.username)">
                {{ scope.row.username }}</span
              >
            </template>
          </el-table-column>
          <el-table-column align="center" :show-overflow-tooltip="true" prop="role" label="角色">
            <template #default="scope">
              <span class="cp" @click.stop="copyText(scope.row.role)"> {{ scope.row.role }}</span>
            </template>
          </el-table-column>
          <el-table-column align="center" prop="avator" label="头像">
            <template #default="scope">
              <el-image
                style="width: 100px; height: 100px"
                :src="baseUrl + scope.row.avator"
                :preview-src-list="[baseUrl + scope.row.avator]"
                :initial-index="0"
                preview-teleported
              >
                <template #error>
                  <div class="nopic">暂无图片</div>
                </template></el-image
              >
            </template>
          </el-table-column>
          <el-table-column
            align="center"
            :show-overflow-tooltip="true"
            prop="btnrole"
            label="按钮权限"
            width="500"
          >
            <template #default="scope">
              <span>
                {{
                  scope.row.btnrole.length == 0 ? "暂无权限" : scope.row.btnrole.join("  ")
                }}</span
              >
            </template>
          </el-table-column>
          <el-table-column align="center" prop="_id" fixed="right" label="操作" width="400">
            <template #default="scope">
              <el-button
                :disabled="!svalue.includes(scope.row._id)"
                color="green"
                @click.stop="distribute(scope.row)"
                :icon="Grid"
                v-hasPermiss="'distribute'"
                >角色</el-button
              >
              <el-button
                :disabled="!svalue.includes(scope.row._id)"
                color="purple"
                @click.stop="btndistribute(scope.row)"
                :icon="Grid"
                v-hasPermiss="'distribute'"
                >按钮</el-button
              >
              <el-button
                type="danger"
                :icon="Delete"
                v-hasPermiss="'delete'"
                :disabled="!svalue.includes(scope.row._id)"
                @click.stop="delusers(scope.row._id)"
              >
                删除
              </el-button>

              <el-button
                type="primary"
                v-hasPermiss="'modify'"
                @click.stop="midify(scope.row)"
                :icon="Edit"
                >修改</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-scrollbar>
  </el-card>
</template>

<script setup lang="ts">
import {
  Delete,
  Edit,
  // Search,
  // Upload,
  CirclePlus,
  RefreshRight,
  Grid,
  // Plus,
} from "@element-plus/icons-vue"
import { VueCropper } from "vue-cropper"
import "vue-cropper/dist/index.css"
import UploadImage from "@/api/upload"
import type { FormInstance, FormRules } from "element-plus"
// import type { UploadInstance } from "element-plus"
import storage from "@/utils/storage"
import { getUsersList, addUser, delUsers, putUsers, getUserInfo } from "@/api/user"
import { getRoleList } from "@/api/role"
import { storeToRefs } from "pinia"
import { useTokenStore } from "@/stores/token"

const ipt = ref<HTMLInputElement | undefined>()
//pinia 的用户信息
let { userinfo } = storeToRefs(useTokenStore())
//设置pinia 的用户信息
let { setUserInfo } = useTokenStore()
//提交的图片文件
// const fileList = ref<any>({})
//前端图片url
const avatarBase64 = ref("")
const avatarBlob = ref(null)
const imageUrl = ref("")
const svg = `
        <path class="path" d="
          M 30 15
          L 28 17
          M 25.61 25.61
          A 15 15, 0, 0, 1, 15 30
          A 15 15, 0, 1, 1, 27.99 7.5
          L 15 15
        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
      `
//提交修改信息时是否修改了图片
// const isChangeImage = ref(false)
const rolelist = ref<any[]>([])
const rolename = ref("")
const afile = ref<File | null>(null)
const convertFile = (base64: string) => {
  let fileArray = base64.split(",") as any[],
    // 过滤出文件类型
    fileType = fileArray[0]?.match(/:(.*?);/)[1],
    // atob 是对经过 base-64 编码的字符串进行解码
    bstr = atob(fileArray[1]),
    n = bstr.length,
    //Uint8Array 数组类型表示一个 8 位无符号整型数组
    u8arr = new Uint8Array(n)
  while (n--) {
    // 返回字符串n个字符的 Unicode 编码
    u8arr[n] = bstr.charCodeAt(n)
  }
  // return new Blob([u8arr], { type: fileType })
  return new File([u8arr], Math.random().toString(), { type: fileType })
}
const btnroleinfo = ref([
  { name: "增加按钮", value: "add" },
  { name: "删除按钮", value: "delete" },
  { name: "全部删除", value: "alldelete" },
  { name: "分配按钮", value: "distribute" },
  { name: "刷新按钮", value: "refresh" },
  { name: "修改按钮", value: "modify" },
  { name: "爬取按钮", value: "pq" },
  { name: "搜索按钮", value: "search" },
  { name: "一键审核按钮", value: "yjsh" },
  { name: "审核按钮", value: "sh" },
])
const btnrole = ref<any[]>([])
const getrolelist = (desc?: string) => {
  getRoleList("/bem/role/getrolelist")
    .then((res) => {
      if (res.code == 200) {
        rolelist.value = res.data
        rolename.value = res.data[0].rolename
      }
      if (desc) {
        ElMessage.success(desc)
      }
    })
    .catch((err: any) => {
      ElMessage.error(JSON.stringify(err))
    })
}
//upload ref实例
// const upload = ref<UploadInstance>()
// //图片状态变化时的函数
// const fileChange = (file: any) => {
//   const isIMAGE = file.type === "image/jpeg" || "image/jpg" || "image/png"
//   const isLt1M = file.size / 1024 / 1024 < 1
//   if (!isIMAGE) {
//     ElMessage.error("上传文件只能是图片格式!")
//     return false
//   }
//   if (!isLt1M) {
//     ElMessage.error("上传文件大小不能超过 1MB!")
//     return false
//   }
//   proxy.$refs.upload.clearFiles()
//   imgSaveToUrl(file.raw)
//   fileList.value = file.raw
//   isChangeImage.value = true
// }
//图片提交时的加载状态
const uloading = ref(false)
//复制功能
const copyText = (text: string) => {
  proxy.$Copy(text)
}
//文件转blob图片在线地址前端展示
// const imgSaveToUrl = (file: any) => {
//   imageUrl.value = URL.createObjectURL(file)
// }
const btndistribute = (item: any) => {
  dialogVisible.value = true
  dialogStatus.value = 3
  putid.value = item._id
  btnrole.value = item.btnrole
  // rolename.value = item.role
}
const distribute = (item: any) => {
  dialogVisible.value = true
  dialogStatus.value = 2
  putid.value = item._id
  rolename.value = item.role
}
//图片提交
const uploadimg = async () => {
  modifyLoading.value = true
  // if (isChangeImage.value) {
  //修改头像和姓名
  const formData = new FormData()
  uloading.value = true
  formData.append("bem", afile.value as Blob)
  UploadImage(formData)
    .then(async (res: any) => {
      if (res.code == 200) {
        ElMessage.success("图片上传成功!")
        let putres = await putUsers("/bem/putuserinfo", {
          id: putid.value,
          avator: "/" + res.data,
          username: username.value,
        })
        if (putres.code == 200) {
          if (putid.value == userinfo.value._id) {
            let ress = await getUserInfo("/bem/getuserinfo")
            if (ress.code == 200) {
              storage.set("userinfo", ress.data.userinfo)
              setUserInfo(ress.data.userinfo)
            }
          }
          getlist("信息修改成功!")
          dialogVisible.value = false
        } else {
          ElMessage.error("信息修改失败!")
        }
      } else {
        ElMessage.error("图片上传失败!")
        dialogVisible.value = false
      }
    })
    .catch((err: any) => {
      console.log("====================================")
      console.log(err)
      console.log("====================================")
    })
    .finally(() => {
      uloading.value = false
      modifyLoading.value = false
    })
}
//formruler 类型
const ruleFormRef = ref<FormInstance>()
//formruler
const rules = reactive<FormRules>({
  phone: [
    { required: true, message: "请输入手机号", trigger: ["blur"] },
    {
      pattern: /^1\d{10}$/,
      message: "手机号格式不正确",
      trigger: ["blur"],
    },
  ],
  password: [
    {
      required: true,
      message: "请输入密码",
      trigger: ["blur"],
    },
  ],
})
//提交用户名
const username = ref("")
//提交id
const putid = ref("")
const { proxy } = getCurrentInstance() as any
//提交删除id
const svalue = ref<any[]>([])
//dialog弹窗显示隐藏
const dialogVisible = ref(false)
//是否为修改状态
// 0add 1 put 2distribute 3btndistribute
const dialogStatus = ref(0)
const zdialogStatus = ref(["增加用户", "修改用户信息", "分配角色", "按钮权限"])
const baseUrl = ref(import.meta.env.VITE_APP_BASE_URL)
//table加载状态
const tableLoading = ref(false)
//增加用户加载状态
// const addLoading = ref(false)
//增加用户加载状态
const modifyLoading = ref(false)
const tableData = ref<any[]>([])
let addform = reactive<{ phone: string; password: string }>({
  phone: "17516211205",
  password: "111",
})
const rclick = (row: any) => {
  if (row.phone != "17516211205") {
    proxy.$refs.fileTable.toggleRowSelection(row)
  } else {
    ElNotification({
      title: "温馨提示",
      message: "禁止选中该用户",
      type: "error",
    })
    return false
  }
}
const selectable: (row: any) => boolean = (row: any) => {
  if (row.phone != "17516211205") {
    return true
  } else {
    return false
  }
}
const openModel = () => {
  dialogVisible.value = true
  dialogStatus.value = 0
}

const submit = () => {
  if (dialogStatus.value == 0) {
    adduser()
  } else if (dialogStatus.value == 1) {
    submodify()
  } else if (dialogStatus.value == 2) {
    modifyLoading.value = true
    putUsers("/bem/putuserinfo", {
      id: putid.value,
      role: rolename.value,
    })
      .then((putres) => {
        if (putres.code == 200) {
          if (putid.value == userinfo.value._id) {
            getUserInfo("/bem/getuserinfo").then((ress) => {
              if (ress.code == 200) {
                storage.set("userinfo", ress.data.userinfo)
                setUserInfo(ress.data.userinfo)
              }
            })
          }
          rolename.value = ""
          getlist("角色分配成功，重新登录后生效!")
        } else {
          ElMessage.error("角色分配失败!")
        }
      })
      .finally(() => {
        modifyLoading.value = false
        dialogVisible.value = false
      })
  } else {
    modifyLoading.value = true
    putUsers("/bem/putuserinfo", {
      id: putid.value,
      btnrole: JSON.stringify(btnrole.value),
    })
      .then((putres) => {
        if (putres.code == 200) {
          if (putid.value == userinfo.value._id) {
            getUserInfo("/bem/getuserinfo").then((ress) => {
              if (ress.code == 200) {
                storage.set("userinfo", ress.data.userinfo)
                setUserInfo(ress.data.userinfo)
              }
            })
          }
          btnrole.value = []
          getlist("按钮权限分配成功，重新登录后生效!")
        } else {
          ElMessage.error("按钮权限分配失败!")
        }
      })
      .finally(() => {
        modifyLoading.value = false
        dialogVisible.value = false
      })
  }
}
const submodify = async () => {
  proxy.$refs.cropper.getCropData(async (data: any) => {
    avatarBlob.value = data
    afile.value = convertFile(data)
    uploadimg()
  })
}
const adduser = async () => {
  if (!ruleFormRef.value) return
  try {
    await ruleFormRef.value.validate(async (valid, fields: any) => {
      if (valid) {
        modifyLoading.value = true
        addUser("/bem/register", addform)
          .then((res: any) => {
            if (res.code == 200) {
              getlist("用户数据增加成功")
              dialogVisible.value = false
              ruleFormRef.value?.resetFields()
            } else {
              ElMessage.error(res.msg)
            }
          })
          .catch((err: any) => {
            ElMessage.error(JSON.stringify(err))
          })
          .finally(() => {
            modifyLoading.value = false
          })
      } else {
        ElMessage.error(fields[Object.keys(fields)[0]][0].message)
      }
    })
  } catch (error) {
    console.log("====================================")
    console.log("服务器网络异常")
    console.log("====================================")
  }
}
const midify = async (info: any) => {
  dialogVisible.value = true
  dialogStatus.value = 1
  let fileEle = document.getElementById("avatarFile")
  fileEle?.click()
  avatarBase64.value = import.meta.env.VITE_APP_BASE_URL + info.avator
  imageUrl.value = import.meta.env.VITE_APP_BASE_URL + info.avator
  username.value = info.username
  putid.value = info._id
}
const delusers = async (val: any) => {
  ElMessageBox.confirm("确定删除此用户?", "提示", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      const loading = ElLoading.service({
        lock: true,
        text: "Loading",
        background: "rgba(0, 0, 0, 0)",
      })
      delUsers("/bem/delusers", {
        ids: Array.isArray(val) ? JSON.stringify([...val]) : JSON.stringify([val]),
      })
        .then((res: any) => {
          if (res.code == 200) {
            ElMessage.success(`成功删除${res.data.num}条用户数据`)
            getlist()
          } else {
            ElMessage.error(res.msg)
          }
        })
        .catch((err: any) => {
          ElMessage.error(JSON.stringify(err))
        })
        .finally(() => {
          loading.close()
        })
    })
    .catch(() => {})
}
const getlist = (desc?: string) => {
  tableLoading.value = true
  getUsersList("/bem/getuserlist")
    .then((res: any) => {
      if (res?.code == 200) {
        tableData.value = res.data
        if (desc) {
          ElMessage.success(desc)
        }
      }
    })
    .catch((err: any) => {
      ElMessage.error(JSON.stringify(err))
    })
    .finally(() => {
      tableLoading.value = false
    })
}

const init = async () => {
  getlist("用户数据加载成功")
  getrolelist()
}
init()
const handleSelectionChange = (val: any) => {
  svalue.value = val.filter((e: any) => e.phone != "17516211205").map((e: any) => e._id)
}
const dels = () => {
  if (svalue.value.length == 0) {
    return ElMessage.error("未勾选要删除的数据")
  }
  delusers(svalue.value)
}
const refresh = () => {
  getlist("用户数据刷新成功")
}
const selectFile = (e: any) => {
  var file = e.target.files[0]
  var reader = new FileReader()
  reader.readAsDataURL(file)
  reader.onload = (e: any) => {
    var imgcode = e.target.result
    avatarBase64.value = imgcode
    dialogStatus.value = 1
  }
}
</script>

<style lang="scss" scoped>
.cp {
  cursor: pointer;
}
.cropperBox {
  width: 100%;
  height: 300px;
  margin-bottom: 40px;
}
.preimage {
  position: relative;
  width: 150px;
  height: 150px;
  display: flex;
  align-items: center;
}
.nopic {
  width: 100px;
  height: 100px;
  background-color: gainsboro;
  display: flex;
  justify-content: center;
  align-items: center;
}
.box-card {
  width: calc(100% - 4px);
  // height: 800px;
  .table {
    width: 100%;
    padding: 10px;
    box-sizing: border-box;
  }
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    .buttons {
      display: flex;
      align-items: center;
    }
  }
}
</style>
